.\" Copyright (C) 2024 Jens Axboe <axboe@kernel.dk>
.\"
.\" SPDX-License-Identifier: LGPL-2.0-or-later
.\"
.TH io_uring_setup_reg_wait 3 "November 2, 2024" "liburing-2.9" "liburing Manual"
.SH NAME
io_uring_setup_reg_wait \- Sets up and registers fixed wait regions
.SH SYNOPSIS
.nf
.B #include <liburing.h>
.PP
.BI "struct io_uring_reg_wait *io_uring_setup_reg_wait(struct io_uring *" ring ","
.BI "                                                  unsigned " nentries ","
.BI "                                                  int *"err ");"
.PP
.fi
.SH DESCRIPTION
.PP
The
.BR io_uring_setup_reg_wait (3)
function allocates and registers a fixed wait region of
.IR nentries
entries. Upon successful return, the function returns a non-NULL pointer. On
error, it returns
.B NULL
and fills in
.IR err
with the error value.

A registered wait region is a contiguous range of
.IR struct io_uring_reg_wait ,
which look as follows:
.PP
.EX
struct io_uring_reg_wait {
    struct __kernel_timespec ts;
    __u32                    min_wait_usec;
    __u32                    flags;
    __u64                    sigmask;
    __u32                    sigmask_sz;
    __u32                    pad[3];
    __u64                    pad2[2];
};
.EE
where
.IR ts
is the wait related information for this wait,
.IR min_wait_usec
is the minimum wait period (for a two-stage wait), if set to non-zero,
.IR flags
tells the kernel about the wait region,
.IR sigmask
is a pointer to a signal mask, if used, and
.IR sigmask_sz
is the size of the signal mask, if used.

Currently the only valid flag is
.B IORING_REG_WAIT_TS ,
which, if set, indicates that the value in
.IR ts
is valid and should be used for the wait operation.

A signal mask is used for the wait, if
.IR sigmask
is set to a valid, non-zero, pointer value. If used,
.IR sigmask_sz
must also be set.

Each of the wait regions are indicated by the offset of the structure. The
first wait region is index
.B 0 ,
the next is index
.B 1 ,
and so forth, up to the registered number of regions set by
.IR nentries.

The wait regions may be modified by an application at any time before calling
.BR io_uring_submit_and_reg_wait (3) .
If modified while a wait region for that given offset is currently in use
by the kernel, the results are undefined - the kernel may see the new value
in time to use it, or it may not.

The main purpose of registered wait regions and the associated submit-and-wait
helpers is to reduce the overhead of a wait operation. A normal wait for
events with a timeout will pass in a
.IR struct io_uring_getevents_arg
which will need to be copied for each wait. For high frequency wait operations,
this adds noticeable overhead for each wait. With registered wait regions,
no such copying needs to take place for each wait.

Once a wait region has been setup, it persists for the life time of the ring.
It's currently not possible to unregister or resize a wait region.
Additionally, a wait region may currently only use a single page of memory.
On a 4k page size system, this means an application is limited to
.B 64
wait regions. That should be enough, as each wait index may be modified as
needed. With at least 64 indices available, hopefully applications can just
use the appropriately setup wait region for each specific type of wait, with
different indices having different wait settings.

While a region cannot get unregistered from the kernel, once a ring has been
closed, the application may free the associated memory by calling
.BR io_uring_free_reg_wait (3) .
An application may also do this before closing a ring, but then wait regions
may no longer be modified by the application.

Available since kernel 6.13.

.SH RETURN VALUE
On success
.BR io_uring_setup_reg_wait (3)
returns a pointer to the start of the wait regions. On failure, it returns
.B NULL
and sets
.IR err
to the appropriate
.BR -errno
value.
.SH SEE ALSO
.BR io_uring_submit_and_wait_reg (3),
.BR io_uring_free_reg_wait (3)
